﻿using System.Collections.Generic;
using Fayshine.VA.RIAService.Web;
using System;
using System.Globalization;
using System.Collections.ObjectModel;
using Fayshine.VA.Models;
using System.Diagnostics;
using System.Net;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Controls;
using LocalBusyIndicator = Fayshine.VA.Controls.BusyIndicator;

namespace Fayshine.VA.Helpers
{
    public delegate void GetUserInfoFinishedEventHandler(user user);
    public class FayshineManager
    {
        #region Private Fields

        private static FayshineManager m_Instance = null;
        private static object m_Sync = new object();
        private FayshineDomainContext m_Context = null;


        public event GetUserInfoFinishedEventHandler GetUserInfoFinished;
        #endregion

        public static int DiagramLineThickness = 1;

        public static DateTime BussinessStartTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 8, 0, 0);
        public static DateTime BussinessEndTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 8, 0, 0);


        #region Constructor

        private FayshineManager()
        {
            m_Context = new FayshineDomainContext();
        }

        public static FayshineManager Instance
        {
            get
            {
                lock (m_Sync)
                {
                    if (m_Instance == null)
                    {
                        m_Instance = new FayshineManager();
                    }
                    return m_Instance;
                }
            }
        }

        #endregion

        #region Public Methods

        public void GetLoginUser(string userName,string pwd)
        {
            var getUserQuery = m_Context.GetUserInfoQuery(userName, pwd);
            var loadUserFinished = m_Context.Load(getUserQuery, (s) => {

                user user = null;
                if (!s.HasError)
                {
                    s.Entities.each(e => {
                        user = e;
                    });
                }
                if (GetUserInfoFinished != null)
                {
                    GetUserInfoFinished(user);
                }
            }, true);
        }

        public List<YearExt> GetYearSource()
        {
            List<YearExt> years = new List<YearExt>();
            //YearExt year1 = new YearExt() { Title = DateTime.Now.Year.ToString(), Year = DateTime.Now.Year };
            //YearExt year2 = new YearExt() { Title = DateTime.Now.AddYears(-1).Year.ToString(), Year = DateTime.Now.AddYears(-1).Year };
            //YearExt year3 = new YearExt() { Title = DateTime.Now.AddYears(-2).Year.ToString(), Year = DateTime.Now.AddYears(-2).Year };
            //YearExt year4 = new YearExt() { Title = DateTime.Now.AddYears(-3).Year.ToString(), Year = DateTime.Now.AddYears(-3).Year };
            //YearExt year5 = new YearExt() { Title = DateTime.Now.AddYears(-4).Year.ToString(), Year = DateTime.Now.AddYears(-4).Year };

            //years.Add(year1);
            //years.Add(year2);
            //years.Add(year3);
            //years.Add(year4);
            //years.Add(year5);

            YearExt year;
            for (int i = 2000; i < 2051; i++)
            {
                year = new YearExt() { Title = i.ToString(), Year = i };
                years.Add(year);
            }


            return years;
        }

        public List<MonthExt> GetMonthSource()
        {
            List<MonthExt> months = new List<MonthExt>();
            MonthExt month1 = new MonthExt() { Title = "一月", Month = 1 };
            MonthExt month2 = new MonthExt() { Title = "二月", Month = 2 };
            MonthExt month3 = new MonthExt() { Title = "三月", Month = 3 };
            MonthExt month4 = new MonthExt() { Title = "四月", Month = 4 };
            MonthExt month5 = new MonthExt() { Title = "五月", Month = 5 };
            MonthExt month6 = new MonthExt() { Title = "六月", Month = 6 };
            MonthExt month7 = new MonthExt() { Title = "七月", Month = 7 };
            MonthExt month8 = new MonthExt() { Title = "八月", Month = 8 };
            MonthExt month9 = new MonthExt() { Title = "九月", Month = 9 };
            MonthExt month10 = new MonthExt() { Title = "十月", Month = 10 };
            MonthExt month11 = new MonthExt() { Title = "十一月", Month = 11 };
            MonthExt month12 = new MonthExt() { Title = "十二月", Month = 12 };

            months.Add(month1);
            months.Add(month2);
            months.Add(month3);
            months.Add(month4);
            months.Add(month5);
            months.Add(month6);
            months.Add(month7);
            months.Add(month8);
            months.Add(month9);
            months.Add(month10);
            months.Add(month11);
            months.Add(month12);

            return months;
        }

        public string GetWeekDayString(DayOfWeek dayOfWeek)
        {
            string weekDay = "星期一";
            switch (dayOfWeek)
            {
                case DayOfWeek.Sunday:
                    weekDay = "星期日";
                    break;
                case DayOfWeek.Monday:
                    weekDay = "星期一";
                    break;
                case DayOfWeek.Tuesday:
                    weekDay = "星期二";
                    break;
                case DayOfWeek.Wednesday:
                    weekDay = "星期三";
                    break;
                case DayOfWeek.Thursday:
                    weekDay = "星期四";
                    break;
                case DayOfWeek.Friday:
                    weekDay = "星期五";
                    break;
                case DayOfWeek.Saturday:
                    weekDay = "星期六";
                    break;
            }

            return weekDay;
        }

        public int GetWeekDayNumber(DayOfWeek dayOfWeek)
        {
            int weekDay = 0;
            switch (dayOfWeek)
            {
                case DayOfWeek.Sunday:
                    weekDay = 6;
                    break;
                case DayOfWeek.Monday:
                    weekDay = 0;
                    break;
                case DayOfWeek.Tuesday:
                    weekDay = 1;
                    break;
                case DayOfWeek.Wednesday:
                    weekDay = 2;
                    break;
                case DayOfWeek.Thursday:
                    weekDay = 3;
                    break;
                case DayOfWeek.Friday:
                    weekDay = 4;
                    break;
                case DayOfWeek.Saturday:
                    weekDay = 5;
                    break;
            }

            return weekDay;
        }

        public int GetWeekNumber(DateTime value)
        {
            return CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(value, CalendarWeekRule.FirstFourDayWeek,DayOfWeek.Monday);
        }

        public int GetYearWeekCount(int strYear)
        {
            System.DateTime fDt = DateTime.Parse(strYear.ToString() + "-01-01");
            int k = Convert.ToInt32(fDt.DayOfWeek);
            if (k == 1)
            {
                int countDay = fDt.AddYears(1).AddDays(-1).DayOfYear;
                int countWeek = countDay / 7 + 1;
                return countWeek;

            }
            else
            {
                int countDay = fDt.AddYears(1).AddDays(-1).DayOfYear;
                int countWeek = countDay / 7 + 2;
                return countWeek;
            }
        }

        public static int GetWeeofYear(DateTime dt)
        {
            CultureInfo ci = new CultureInfo("zh-CN");
            System.Globalization.Calendar cal = ci.Calendar;
            CalendarWeekRule cwr = ci.DateTimeFormat.CalendarWeekRule;
            DayOfWeek dow = DayOfWeek.Sunday;
            int week = cal.GetWeekOfYear(DateTime.Now, cwr, dow);
            return week;

        }

        public bool ValidateAreaGateInputs(List<AreaExtend> areas, List<MonitorAreaGateExt> gates, ref string errMsg)
        {
            bool bRet = true;

            errMsg = "请选择店铺和门面！";

            if (areas == null || areas.Count == 0)
            {
                bRet = false;
            }
            else if (areas.Count == 1)
            {
                if (gates == null || gates.Count == 0)
                {
                    bRet = false;
                }
            }

            return bRet;
        }

        public static void GetWeekDate(DateTime dt, out DateTime dtWeekStart, out DateTime dtWeekEnd)
        {
            // 一周范围转成周一到周日
            if (dt.DayOfWeek == DayOfWeek.Sunday)
            {
                dtWeekEnd = dt;
            }
            else
            {
                // dtWeekEnd is saturday
                dtWeekEnd = dt.AddDays((double)(7 - dt.DayOfWeek));
            }

            dtWeekStart = dtWeekEnd.AddDays(-6);

            Debug.Assert(dtWeekEnd.DayOfWeek == DayOfWeek.Sunday);
            Debug.Assert(dtWeekStart.DayOfWeek == DayOfWeek.Monday);
        }

        public void ExportToDisk(SaveFileDialog fsd, UIElement spContent)
        {

            //Create WriteableBitmap object which is what is being exported.
            WriteableBitmap wBitmap = new WriteableBitmap(spContent, null);


            int hgt = wBitmap.PixelHeight;
            int wdth = wBitmap.PixelWidth;

            //Create EditableImage oblect and iterrate through WriteableBitmap pixels to set EditableImage pixels
            EditableImage ei = new EditableImage(wdth, hgt);

            for (int y = 0; y < hgt; y++)
            {
                for (int x = 0; x < wdth; x++)
                {
                    int pixel = wBitmap.Pixels[((y * wdth) + x)];
                    //if (pixel < 0) pixel = 0;
                    ei.SetPixel(x, y, (byte)((pixel >> 16) & 0xff), (byte)((pixel >> 8) & 0xff), (byte)(pixel & 0xff), (byte)((pixel >> 24) & 0xff));
                }
            }

            //Get the stream from the encoder and create byte array from it
            System.IO.Stream pngStream = ei.GetStream();

            printBuffer = new Byte[pngStream.Length];
            pngStream.Read(printBuffer, 0, printBuffer.Length);

            switch (fsd.FilterIndex)
            {
                case 1:
                    HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create(new Uri(Application.Current.Host.Source.ToString().Substring(0, Application.Current.Host.Source.ToString().LastIndexOf("/")) + "/Png2Pdf.ashx"));
                    hwr.Method = "POST";

                    printStream = fsd.OpenFile();
                    printSyncContext = System.Threading.SynchronizationContext.Current;
                    hwr.BeginGetRequestStream(new AsyncCallback(PrintStart), hwr);

                    break;
                case 2:
                    //Save the PNG to local disk
                    System.IO.Stream fs = fsd.OpenFile();
                    fs.Write(printBuffer, 0, printBuffer.Length);
                    fs.Close();
                    MessageBox.Show("You PNG has been created.", "Export Complete", MessageBoxButton.OK);
                    break;
            }

        }

        #endregion

        #region Export PDF

        private Byte[] printBuffer;
        private System.Threading.SynchronizationContext printSyncContext;
        private System.IO.Stream printStream;

        private void PrintStart(IAsyncResult asynchronousResult)
        {
            HttpWebRequest hwr = (HttpWebRequest)asynchronousResult.AsyncState;
            System.IO.Stream stream = (System.IO.Stream)hwr.EndGetRequestStream(asynchronousResult);

            stream.Write(printBuffer, 0, printBuffer.Length);
            stream.Close();

            hwr.BeginGetResponse(new AsyncCallback(PrintGetResponse), hwr);
        }

        private void PrintGetResponse(IAsyncResult asynchronousResult)
        {
            HttpWebRequest hwr = (HttpWebRequest)asynchronousResult.AsyncState;
            WebResponse resp = hwr.EndGetResponse(asynchronousResult);
            System.IO.Stream respStream = resp.GetResponseStream();
            Byte[] respBytes = new Byte[respStream.Length];

            respStream.Read(respBytes, 0, respBytes.Length);

            printSyncContext.Post(PrintMergeThreads, new HttpWebRequestData(hwr, respBytes));
        }

        private void PrintMergeThreads(object state)
        {
            HttpWebRequestData hwrd = (HttpWebRequestData)state;

            printStream.Write(hwrd.Data, 0, hwrd.Data.Length);
            printStream.Close();
            printStream = null;
            printSyncContext = null;

            LocalBusyIndicator indicator = Application.Current.RootVisual as LocalBusyIndicator;
            indicator.IsBusy = false;

            MessageBox.Show("Your PDF has been created.", "Export Complete", MessageBoxButton.OK);
        }

        #endregion
    }

    public class YearExt
    {
        public string Title { get; set; }
        public int Year { get; set; }
    }

    public class MonthExt
    {
        public string Title { get; set; }
        public int Month { get; set; }
    }


}
